package info.emamian.droplet.core.provider;

import info.emamian.droplet.core.domain.BasicSMS;

import java.io.IOException;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.twilio.sdk.verbs.Sms;
import com.twilio.sdk.verbs.TwiMLException;
import com.twilio.sdk.verbs.TwiMLResponse;

/**
 * @author Peyman
 * 
 *         provider phone number 701-466-5090
 */
public class DHTwilio {
	private static final Logger log = LoggerFactory.getLogger(DHTwilio.class);
	private static final String PROVIDER_NAME = "Twilio.com";

	public static BasicSMS convertToBasicSMS(HttpServletRequest request) {
		BasicSMS incoming = convertHttpRequestToIncomingSMS(request);
		return incoming;
	}

	public static BasicSMS writeTwimlResponse(BasicSMS incoming, HttpServletResponse response, String responseText) {
		if (response == null) {
			log.error("response was null");
			return null;
		}
		if (responseText == null || responseText.trim().isEmpty()) {
			log.error("responseText was null or empty");
			return null;
		}
		TwiMLResponse twiml = getTwimlResponse(responseText);
		if (twiml == null) {
			log.error("could not create Twiml for responseText " + responseText);
			return null;
		}
		response.setContentType("application/xml");
		try {
			response.getWriter().print(twiml.toXML());
			// save to DB
			Map<String, String> props = new HashMap<String, String>();
			props.put("responseTo", incoming.getId());
			BasicSMS outgoing = new BasicSMS(incoming.getTo(), incoming.getFrom(), responseText, PROVIDER_NAME, new Date(), false, props);
			return outgoing;
		} catch (IOException e) {
			log.error("Could not write twiML to HttpServletResponse ", e);
			return null;
		}
	}

	private static BasicSMS convertHttpRequestToIncomingSMS(HttpServletRequest request) {
		Map<String, String> properties = new HashMap<String, String>();
		Enumeration<?> c = request.getParameterNames();
		while (c.hasMoreElements()) {
			String el = (String) c.nextElement();
			if (el == null)
				continue;
			properties.put(el.toString(), request.getParameter(el));
			log.info("request param [{}] -> [{}]", el, request.getParameter(el));
		}
		properties.put("remoteAddr", request.getRemoteAddr());
		log.debug("Incoming message properties:{}", properties);
		String from = request.getParameter("From");
		String to = request.getParameter("To");
		String body = request.getParameter("Body");
		BasicSMS incomingSMS = new BasicSMS(from, to, body, PROVIDER_NAME, new Date(), true, properties);
		log.info("DHTwilio received & saved: {}", incomingSMS);
		return incomingSMS;
	}

	/**
	 * Creates a TwiMLResponse for the msg
	 * 
	 * @param msg
	 * @return null if not successful
	 */
	public static TwiMLResponse getTwimlResponse(String msg) {
		Sms responseSMS = new Sms(msg);
		TwiMLResponse twiml = new TwiMLResponse();
		try {
			twiml.append(responseSMS);
		} catch (TwiMLException e) {
			log.info(String.format("Error appending responseSms [{}] to TwiMLResponse [{}]", responseSMS.toString(), twiml.toString()), e);
			return null;
		}
		return twiml;
	}
}
